package com.errol.batchprocessor.batchprocessor;

import com.renjia.entity.AbstractImportBatch;
import com.renjia.service.generic.middleware.batchprocessor.bo.ThreadPoolAndMissionStatusBO;
import com.renjia.service.generic.middleware.batchprocessor.bo.ThreadPoolStatusBO;
import com.renjia.service.generic.middleware.batchprocessor.payload.AbstractBatchPayload;
import com.renjia.service.generic.middleware.batchprocessor.payload.AbstractPiecePayload;
import com.renjia.service.generic.middleware.batchprocessor.payload.AbstractSinglePayload;

import java.util.List;

/**
 * 导入、添加人员的执行服务，包括线程池的使用、主流程和扩展点的设计
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/02/22
 * @since v5.0.5
 **/
public interface BatchProcessor<IE extends AbstractImportBatch, AT extends Enum<?>, BE, SE, BP extends AbstractBatchPayload<IE, AT, BE, SE>, PP extends AbstractPiecePayload<SE, SP>, SP extends AbstractSinglePayload<SE>> {

    /**
     * 将任务加入批处理线程池
     *
     * @param batchPayload 批次数据
     */
    void startMission(BP batchPayload);

    /**
     * 对批次进行分片
     * doSplitBatch doProcessSingleRecord doCleanBatch 搭配使用作为单条数据处理的固定流程
     *
     * @param batchPayload 批次数据
     * @return 分片列表
     */
    List<PP> doSplitBatch(BP batchPayload);

    /**
     * 同步处理一条数据，处理逻辑 同批处理中处理一条记录
     * 处理一条数据的过程中，不应修改 批次数据 中数据
     * doSplitBatch doProcessSingleRecord doCleanBatch 搭配使用作为单条数据处理的固定流程
     *
     * @param singlePayload 单条数据
     * @param piecePayload  分片数据
     * @param batchPayload  批次数据
     * @return false 表示执行异常；true 表示成功正常
     */
    boolean doProcessSingleRecord(SP singlePayload, PP piecePayload, BP batchPayload);

    /**
     * 清理批次缓存
     * doSplitBatch doProcessSingleRecord doCleanBatch 搭配使用作为单条数据处理的固定流程
     *
     * @param batchPayload 批次数据
     */
    void doCleanBatch(BP batchPayload);

    /**
     * 获取线程池状态信息
     *
     * @return 线程池主要参数和状态
     */
    ThreadPoolStatusBO getThreadPoolStatus();

    /**
     * 获取线程池和任务状态信息
     *
     * @return 线程池主要参数和任务执行进展信息
     */
    ThreadPoolAndMissionStatusBO getMissionStatus();

    /**
     * 设置线程池核心线程数，最大线程数固定为 1.5 倍
     *
     * @param targetCorePoolSize 目标核心线程数，扩大时最多增加一半，缩小时最多减少一半
     * @return 实际设置的核心线程数
     */
    int setCorePoolSize(int targetCorePoolSize);
}
